/*
	功能：从消息队列读取数据，提交到fabric，并将调用结果通过callback发送给请求方
*/
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"

	"fabric-fpsp/ccsdk"

	"github.com/nsqio/go-nsq"
)

type myMessageHandler struct {
	TopicName string
}

func (h *myMessageHandler) processMessage(bodyData []byte) error {

}

// 元数据中不能再有密码，否则不安全
func (h *myMessageHandler) callRegister(bodyData []byte) error {
	regDataMap := make(map[string]interface{})
	err := json.Unmarshal(bodyData, regDataMap)
	if err != nil {
		return err
	}

}

// 对消息内容进行分流
func (h *myMessageHandler) HandleMessage(m *nsq.Message) error {
	fmt.Println("begin process msg")
	if len(m.Body) == 0 {
		// Returning nil will automatically send a FIN command to NSQ to mark the message as processed.
		// In this case, a message with an empty body is simply ignored/discarded.
		return nil
	}

	// do whatever actual message processing is desired
	//err := processMessage(m.Body)
	fmt.Printf("get msg:%s\n", m.Body)
	if len(m.Body) < 8 {
		return nil
	}
	map11 := make(map[string]interface{})
	err := json.Unmarshal(m.Body, &map11)
	if err != nil {
		fmt.Printf("Failed to HandleMessage %s\n", err)
		return err
	}

	fmt.Printf("%+v\n", map11)
	sendMsg(map11["callback"].(string), "POST", m.Body)

	// Returning a non-nil error will automatically send a REQ command to NSQ to re-queue the message.
	return nil
}

func topic_consumer(topicName string) {
	// Instantiate a consumer that will subscribe to the provided channel.
	config := nsq.NewConfig()
	consumer, err := nsq.NewConsumer(topicName, "channel", config)
	if err != nil {
		log.Fatal(err)
	}

	// Set the Handler for messages received by this Consumer. Can be called multiple times.
	// See also AddConcurrentHandlers.
	consumer.AddHandler(&myMessageHandler{topicName})

	// Use nsqlookupd to discover nsqd instances.
	// See also ConnectToNSQD, ConnectToNSQDs, ConnectToNSQLookupds.
	err = consumer.ConnectToNSQLookupd("localhost:4161")
	if err != nil {
		log.Fatal(err)
	}
	// wait for signal to exit
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	<-sigChan

	// Gracefully stop the consumer.
	consumer.Stop()
	wg.Done()
}

func sendMsg(url string, method string, data []byte) error {
	req, err := http.NewRequest(method, url, bytes.NewBuffer(data))
	if err != nil {
		fmt.Printf("failed to NewRequest %s\n", err)
		return err
	}

	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)

	if err != nil {
		panic(err)
	}

	defer resp.Body.Close()
	fmt.Println("response Status:", resp.Status)
	fmt.Println("response Headers:", resp.Header)
	body, _ := ioutil.ReadAll(resp.Body)

	fmt.Println("response Body:", string(body))
	return nil
}

var wg sync.WaitGroup

func main() {
	wg.Add(1)
	//go topic_consumer("topic")
	go topic_consumer("register")
	wg.Wait()
}
